﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Ant.Component
{
    class TcpUtilInit
    {
        static TcpUtilInit()
        {
            Beetle.TcpUtils.DataPacketMaxLength = 1024 * 128;
            Beetle.TcpUtils.SendBufferLength = 1024 * 8;
            Beetle.TcpUtils.Setup(10, 1, 1);
            Beetle.PacketAnalysis.Setup(1);
        }
        public static void Init()
        {
        }
    }
    public class Updater
    {

        public string Message
        {
            get;
            set;
        }
        private Beetle.TcpChannel mChannel;
        private System.Threading.AutoResetEvent mResetEvent = new System.Threading.AutoResetEvent(false);
        bool mDetectResult = false;
        private Exception mError = null;
        public bool Detect(string address, int port)
        {
            try
            {
                System.Net.IPAddress[] ips = System.Net.Dns.GetHostAddresses(address);
                if (ips == null || ips.Length == 0)
                {
                    Message = "访问地址无效!";
                    return false;
                }


                return Detect(ips[0], port);
            }
            catch (Exception e_)
            {
                Message = e_.Message;
                return false;
            }
        }
        private bool Detect(System.Net.IPAddress ip, int port)
        {
            try
            {
                TcpUtilInit.Init();

                mChannel = Beetle.TcpServer.CreateClient(new System.Net.IPEndPoint(ip, port));
                Beetle.ChannelAdapter adapter = new Beetle.ChannelAdapter(
                    mChannel, new Beetle.HeadSizePackage(Protocols.MessageBase.GetMessage));
                adapter.Receive += Receive;
                mChannel.BeginReceive();
                mResetEvent.Reset();
                Protocols.GetUpdateInfo getinfo = new Protocols.GetUpdateInfo();
                adapter.Send(getinfo);
                if (!mResetEvent.WaitOne(10000) && mError == null)
                {
                    Message = "访问超时!";
                }
                if (mError != null)
                    Message = mError.Message;
            }
            catch (Exception e_)
            {
                Message = e_.Message;
            }
            return mDetectResult;
        }
        private void OnError(object sender, Beetle.ChannelErrorEventArgs e)
        {
            mError = e.Exception;
            mResetEvent.Set();
        }
        private void Receive(Beetle.ChannelAdapter adapter, Beetle.IMessage e)
        {
            if (e is Component.Protocols.GetUpdateInfoResponse)
            {
                GetUpdageInfo(adapter, (Component.Protocols.GetUpdateInfoResponse)e);
            }
        }
        public void Updating(string address, int port, string appname, bool autoclose)
        {
            System.Net.IPAddress[] ips = System.Net.Dns.GetHostAddresses(address);
            System.Diagnostics.Process.Start("Ant.Update.exe", string.Format("{0} {1} {2} {3}", ips[0], port, appname, autoclose));
        }
        public void GetUpdageInfo(Beetle.ChannelAdapter adapter, Protocols.GetUpdateInfoResponse e)
        {
            if (!string.IsNullOrEmpty(e.Status))
                mError = new Exception(e.Status);
            UpdateInfo local = GetLocalInfo();
            UpdateInfo remot = new UpdateInfo();
            remot.LoadXml(e.Info);
            mDetectResult = local.Comparable(remot).Count > 0;
            adapter.Channel.Dispose();
            mResetEvent.Set();

        }
        public void ProcessMessage(Beetle.ChannelAdapter adapter, Beetle.MessageHandlerArgs message)
        {

        }
        private UpdateInfo GetLocalInfo()
        {
            UpdateInfo info = new UpdateInfo();
            string filename = System.IO.Path.GetDirectoryName(typeof(Updater).Assembly.Location) + "\\update_info.xml";
            info.Load(filename);
            return info;
        }
    }
}
